Module('Phosphor.Utilities', function () {
    var hasOwn = Object.prototype.hasOwnProperty;

    function extend(destination, source) {
        for (var k in source) if (hasOwn.call(source, k)) {
            destination[k] = source[k];
        }
    }

    function Class(options){
        var Extends = options.Extends || Object,
            Mixins = options.Mixins || [],
            prototype = Object.beget(Extends.prototype);

        delete options.Extends;
        delete options.Mixins;

        function Constructor() {
            // If not invoked with 'new' keyword, still
            // return an instance of Constructor
            var instance;
            if (!(this instanceof Constructor)) {
                instance = Object.beget(Constructor.prototype);
                Constructor.apply(instance, arguments);
                return instance;
            }

            if (typeof this.initialize == 'function') {
                this.initialize.apply(this, arguments);
            }
        }

        // Add the mixins properties
        Mixins.forEach(function (Mixin) {
            extend(prototype, Mixin.prototype);
        });

        // add the explicit properties
        extend(prototype, options);

        Constructor.prototype = prototype;
        Constructor.__super__ = Extends.prototype;

        prototype.constructor = Constructor;
        prototype.__prototype__ = prototype;

        return Constructor;
    }

    // So that `(new Class() instanceof Class) == true`
    Class.prototype = Function.prototype; 
    this.Class = Class;

    // Options mixin
    var Options = new Class({
        options: {},

        setOptions: function (options) {
            options = options != null ? options : {};
            var hasOwn = Object.prototype.hasOwnProperty;

            for (var k in options) if (hasOwn.call(options, k)) {
                this.options[k] = options[k];
            }
        }
    });

    this.Options = Options;    
});
